﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ScintillaNET;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace Xejen.Editor
{
    /// <summary>
    /// 表示显示数据的窗体
    /// </summary>
    /// <creator>marc</creator>
    public partial class DataVisualizeForm : FormBase
    {
        /// <summary>
        /// 采用哪种语言的语法
        /// </summary>
        private readonly string _language;

        private readonly Scintilla _editor;

        /// <summary>
        /// 数据
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string Data { get; set; }

        /// <summary>
        /// 窗体标题
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string Title { get; set; }

        /// <inheritdoc cref="DataVisualizeForm"/>
        /// <param name="data">待可视化的数据</param>
        /// <param name="title">窗体标题</param>
        /// <param name="language">采用哪种语言的高亮语法（区分大小写）。<br/>若传空则自动识别，目前支持自动识别：json 和 xml</param>
        /// <param name="readWriteType"><inheritdoc cref="ReadWriteType" path="/summary"/></param>
        public DataVisualizeForm(string data, string title = null, string language = null, ReadWriteType readWriteType = ReadWriteType.Read)
        {
            Data = data;
            Title = title;
            _language = language;

            InitializeComponent();

            _editor = new Scintilla
            {
                //Font = new System.Drawing.Font("Consolas", 9),
                //Font = new System.Drawing.Font("新宋体", 10),
                //Font = new System.Drawing.Font("微软雅黑", 9),
                Font = new System.Drawing.Font("宋体", 10),
                Dock = DockStyle.Fill,
            };
            ContainerPanel.Controls.Add(_editor);

            if (readWriteType == ReadWriteType.Write)
            {
                SavePanel.Visible = true;
            }
        }

        /// <inheritdoc/>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!string.IsNullOrEmpty(Title))
            {
                this.Text = Title;
            }

            LoadEditor();
        }

        private void LoadEditor()
        {
            string content = Data;
            string language = null;
            if (!string.IsNullOrEmpty(Data))
            {
                if (Data.IsJson())
                {
                    content = Data.FormatJson();
                    language = "json";
                    ConfigureJsonSyntaxHighlighting(_editor);
                }
                else if (Data.IsXml())
                {
                    content = Data.FormatXml();
                    language = "xml";
                    ConfigureXmlSyntaxHighlighting(_editor);
                }
            }

            _editor.Text = content;
            _editor.LexerName = _language ?? language;

            SaveButton.Enabled = true;
        }

        /// <summary>
        /// 预加载
        /// </summary>
        public void Preload()
        {
            LoadEditor();
        }

        private void ConfigureXmlSyntaxHighlighting(Scintilla scintilla)
        {
            scintilla.Styles[Style.Xml.Default].ForeColor = System.Drawing.Color.Silver;          // 默认颜色
            scintilla.Styles[Style.Xml.Tag].ForeColor = System.Drawing.Color.Blue;                // 标签名
            scintilla.Styles[Style.Xml.TagEnd].ForeColor = System.Drawing.Color.Blue;             // 结束标签名
            scintilla.Styles[Style.Xml.Attribute].ForeColor = System.Drawing.Color.Red;           // 属性名
            scintilla.Styles[Style.Xml.AttributeUnknown].ForeColor = System.Drawing.Color.Red;    // 未知属性
            scintilla.Styles[Style.Xml.Comment].ForeColor = System.Drawing.Color.Green;           // 注释
            scintilla.Styles[Style.Xml.Number].ForeColor = System.Drawing.Color.Olive;            // 数字
            scintilla.Styles[Style.Xml.DoubleString].ForeColor = System.Drawing.Color.Maroon;     // 双引号字符串
            scintilla.Styles[Style.Xml.SingleString].ForeColor = System.Drawing.Color.Maroon;     // 单引号字符串
            scintilla.Styles[Style.Xml.Other].ForeColor = System.Drawing.Color.Purple;            // 其他文本
            scintilla.Styles[Style.Xml.Entity].ForeColor = System.Drawing.Color.Teal;             // 实体引用
            scintilla.Styles[Style.Xml.XmlStart].ForeColor = System.Drawing.Color.Blue;           // XML 声明
            scintilla.Styles[Style.Xml.XmlEnd].ForeColor = System.Drawing.Color.Blue;             // XML 声明结束
            scintilla.Styles[Style.Xml.CData].ForeColor = System.Drawing.Color.Gray;              // CDATA 部分
            //scintilla.Styles[Style.Xml.DocType].ForeColor = System.Drawing.Color.Gray;            // 文档类型
        }

        private void ConfigureJsonSyntaxHighlighting(Scintilla scintilla)
        {
            // 设置 JSON 语法高亮颜色
            scintilla.Styles[Style.Json.Default].ForeColor = System.Drawing.Color.Black;          // 默认颜色
            scintilla.Styles[Style.Json.BlockComment].ForeColor = System.Drawing.Color.Green;     // 注释
            scintilla.Styles[Style.Json.LineComment].ForeColor = System.Drawing.Color.Green;      // 行注释
            scintilla.Styles[Style.Json.Number].ForeColor = System.Drawing.Color.Blue;            // 数字
            scintilla.Styles[Style.Json.PropertyName].ForeColor = System.Drawing.Color.SteelBlue; // 属性名
            scintilla.Styles[Style.Json.String].ForeColor = System.Drawing.Color.FromArgb(163, 21, 21); // 字符串
            //scintilla.Styles[Style.Json.Character].ForeColor = System.Drawing.Color.Brown;        // 字符（类似字符串）
            scintilla.Styles[Style.Json.Keyword].ForeColor = System.Drawing.Color.Blue;           // 关键字（true, false, null）
            scintilla.Styles[Style.Json.Operator].ForeColor = System.Drawing.Color.Black;         // 操作符（如 : , { } [ ])

            // 可选：调整背景色或其他样式属性
            scintilla.Styles[Style.Json.BlockComment].BackColor = System.Drawing.Color.White; // 背景色
            scintilla.Styles[Style.Json.BlockComment].Italic = true;                         // 斜体
        }

        /// <summary>
        /// 设置界面大小
        /// </summary>
        /// <param name="size">界面大小值设定</param>
        public void SetClientSize(Size size)
        {
            this.ClientSize = size;
        }

        /// <summary>
        /// 设置保存按钮的文字
        /// </summary>
        /// <param name="text">文字</param>
        public void SetSaveButtonText(string text)
        {
            SaveButton.Text = text;
        }

        /// <summary>
        /// 获取文本数据内容
        /// </summary>
        /// <returns></returns>
        public async Task<string> GetDataAsync()
        {
            return await Task.FromResult(_editor.Text);
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveButton_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
        }
    }

    /// <summary>
    /// 表示读写类型
    /// </summary>
    public enum ReadWriteType : short
    {
        /// <summary>
        /// 读，这是默认的
        /// </summary>
        Read = 0,
        /// <summary>
        /// 写
        /// </summary>
        Write = 1,
    }
}
